package db

import (
	"fmt"
	"ginApi/config"
	"github.com/gomodule/redigo/redis"
	"github.com/pelletier/go-toml"
	"log"
	"time"
)

var RDS *RedisConn

type RedisConn struct {
	pool      *redis.Pool
	showDebug bool
}

func (rds *RedisConn) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
	conn := rds.pool.Get()
	defer conn.Close()

	t1 := time.Now().UnixNano()
	reply, err = conn.Do(commandName, args...)
	if err != nil {
		e := conn.Err()
		if e != nil {
			log.Println("redis Do", err, e)
		}
	}
	t2 := time.Now().UnixNano()
	if rds.showDebug {
		fmt.Printf("[redis] [info] [%dus]cmd=%s, err=%s, args=%v, reply=%s\n", (t2-t1)/1000, commandName, err, args, reply)
	}
	return reply, err
}

func (rds *RedisConn) ShowDebug(b bool) {
	rds.showDebug = b
}

func Redis() {
	c := config.Conf.Get("redis").(*toml.Tree)

	host := c.Get("host").(string)
	port := c.Get("port").(int64)
	password := c.Get("password").(string)
	maxIdle := int(c.Get("maxIdle").(int64))
	maxActive := int(c.Get("maxActive").(int64))
	idleTimeout := time.Duration(c.Get("idleTimeout").(int64))
	wait := c.Get("wait").(bool)
	maxConnLifetime := time.Duration(c.Get("maxConnLifetime").(int64))

	pool := redis.Pool{
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", fmt.Sprintf("%s:%d", host, port))
			if err != nil {
				//log.Fatal("redis Dial error ", err)
				panic("redis Dial error " + err.Error())
				return nil, err
			}
			if password != "" {
				if _, err := c.Do("AUTH", password); err != nil {
					c.Close()
					return nil, err
				}
			}
			return c, nil
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			if time.Since(t) < time.Minute {
				return nil
			}
			_, err := c.Do("PING")
			return err
		},
		MaxIdle:         maxIdle,
		MaxActive:       maxActive,
		IdleTimeout:     idleTimeout,
		Wait:            wait,
		MaxConnLifetime: maxConnLifetime,
	}

	RDS = &RedisConn{
		pool: &pool,
	}
}
